using System.Security.Cryptography;
using System.Text;
using System.Text.Json;

namespace LicenseApp.Client;

/// <summary>
/// 授权验证器 - 客户端只能验证，不能生成
/// </summary>
public class LicenseValidator
{
    /// <summary>
    /// 内部授权数据结构（用于JSON反序列化）
    /// </summary>
    private class LicenseData
    {
        public string StartDate { get; set; } = "";
        public int Days { get; set; }
        public int AgvCount { get; set; }
        public string MachineCode { get; set; } = "";  // 机器码（可选）
        public string Signature { get; set; } = "";
    }

    // 应用程序路径获取 - 按要求实现
    public static string assemblyFilePath = System.Diagnostics.Process.GetCurrentProcess().MainModule?.FileName ?? "";
    public static string assemblyDirPath = System.IO.Path.GetDirectoryName(assemblyFilePath) ?? "";
    public static string PATH = assemblyDirPath;

    private static readonly string LicenseFilePath = System.IO.Path.Combine(PATH, "System.ZhyLsHK.dll");
    private static readonly string PublicKeyFilePath = System.IO.Path.Combine(PATH, "public.xml");

    // 应用启动时间（用于宽限期判断）
    private static readonly DateTime _applicationStartTime = DateTime.Now;

    /// <summary>
    /// 设置公钥（通常在应用程序初始化时调用一次）
    /// </summary>
    /// <param name="publicKeyXml">RSA公钥XML字符串</param>
    /// <returns>是否设置成功</returns>
    public static bool SetPublicKey(string publicKeyXml)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(publicKeyXml))
                return false;

            // 验证公钥格式
            using var rsa = RSA.Create();
            rsa.FromXmlString(publicKeyXml);

            // 保存公钥到文件
            System.IO.File.WriteAllText(PublicKeyFilePath, publicKeyXml, Encoding.UTF8);
            return true;
        }
        catch
        {
            return false;
        }
    }

    /// <summary>
    /// 注册授权码
    /// </summary>
    /// <param name="licenseCode">Base64编码的授权码</param>
    /// <returns>是否注册成功</returns>
    public static bool RegisterLicense(string licenseCode)
    {
        return RegisterLicense(licenseCode, false);
    }

    /// <summary>
    /// 注册授权码（带确认参数）
    /// </summary>
    /// <param name="licenseCode">Base64编码的授权码</param>
    /// <param name="confirmed">是否已确认风险</param>
    /// <returns>是否注册成功</returns>
    public static bool RegisterLicense(string licenseCode, bool confirmed)
    {
        try
        {
            if (string.IsNullOrWhiteSpace(licenseCode))
                return false;

            // 🎯 检查注册风险和合法性
            var riskCheck = CheckDuplicateRegistration(licenseCode);

            if (!riskCheck.CanRegister)
            {
                Console.WriteLine($"[LicenseValidator] 注册被拒绝: {riskCheck.Message}");
                return false;
            }

            // 🎯 如果需要确认但用户未确认，拒绝注册
            if (riskCheck.RequiresConfirmation && !confirmed)
            {
                Console.WriteLine($"[LicenseValidator] 需要用户确认风险: {riskCheck.Message}");
                return false;
            }

            // 验证授权码格式和签名
            var licenseInfo = ValidateLicenseCode(licenseCode);
            if (licenseInfo == null)
            {
                Console.WriteLine("[LicenseValidator] 授权码验证失败：格式错误或签名无效");
                return false;
            }

            // 🎯 完整验证：检查时间和使用天数
            var validation = UnifiedLicenseGuard.ValidateLicense(licenseInfo);
            if (!validation.IsValid)
            {
                Console.WriteLine($"[LicenseValidator] 授权码验证失败：{validation.Message}");
                return false;
            }

            // 🎯 使用统一防护器保存授权码
            bool saveSuccess = UnifiedLicenseGuard.SaveLicense(licenseCode);
            Console.WriteLine($"[LicenseValidator] 授权注册: {(saveSuccess ? "成功" : "失败")}");

            // 清除缓存，强制重新加载
            _cachedLicenseInfo = null;
            _lastCacheTime = DateTime.MinValue;

            return true;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"[LicenseValidator] 注册异常: {ex.Message}");
            return false;
        }
    }

    private static LicenseInfo? _cachedLicenseInfo;
    private static DateTime _lastCacheTime = DateTime.MinValue;
    private static readonly TimeSpan CacheTimeout = TimeSpan.FromMinutes(5); // 缓存5分钟

    /// <summary>
    /// 获取当前授权信息
    /// </summary>
    /// <returns>授权信息，如果无效则返回null</returns>
    public static LicenseInfo? GetLicenseInfo()
    {
        try
        {
            // 检查缓存是否有效
            if (_cachedLicenseInfo != null && DateTime.Now - _lastCacheTime < CacheTimeout)
            {
                return _cachedLicenseInfo;
            }

            // 🎯 使用统一防护器加载授权码
            var licenseCode = UnifiedLicenseGuard.LoadLicense();
            if (string.IsNullOrEmpty(licenseCode))
                return null;
            var licenseInfo = ValidateLicenseCode(licenseCode);

            // 🎯 使用统一防护器验证授权和时间
            if (licenseInfo != null)
            {
                var validation = UnifiedLicenseGuard.ValidateLicense(licenseInfo);
                if (!validation.IsValid)
                {
                    Console.WriteLine($"[LicenseValidator] 授权验证失败");
                    return null;
                }

                // 更新授权信息
                licenseInfo.RemainingDays = validation.RemainingDays;
                Console.WriteLine($"[LicenseValidator] 授权验证通过，剩余{validation.RemainingDays}天");
            }

            // 更新缓存
            _cachedLicenseInfo = licenseInfo;
            _lastCacheTime = DateTime.Now;

            return licenseInfo;
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 检查授权是否有效（考虑宽限期）
    /// </summary>
    /// <returns>是否有效</returns>
    public static bool IsLicenseValid()
    {
        var statusInfo = GetLicenseStatus();
        return statusInfo.Status == LicenseStatus.Valid || statusInfo.Status == LicenseStatus.ExpiringSoon || statusInfo.Status == LicenseStatus.ExpiredGracePeriod;
    }

    /// <summary>
    /// 获取详细的授权状态信息
    /// </summary>
    /// <returns>授权状态信息</returns>
    public static LicenseStatusInfo GetLicenseStatus()
    {
        try
        {
            var licenseInfo = GetLicenseInfo();
            if (licenseInfo == null)
            {
                // 🎯 详细分析无授权的原因
                string detailedMessage = AnalyzeNoLicenseReason();

                return new LicenseStatusInfo
                {
                    Status = LicenseStatus.Expired,
                    Message = detailedMessage,
                    CheckTime = DateTime.Now
                };
            }

            // 🎯 使用统一防护器验证
            var validation = UnifiedLicenseGuard.ValidateLicense(licenseInfo);

            return new LicenseStatusInfo
            {
                Status = validation.IsValid ? LicenseStatus.Valid : LicenseStatus.Expired,
                Message = validation.Message,
                CheckTime = validation.CurrentTime,
                RemainingDays = validation.RemainingDays,
                UsedDays = validation.UsedDays,
                ExpiryDate = licenseInfo.EndDate,
                // 🎯 新增：包含详细的验证结果
                ValidationResult = validation,
                RuleDetails = validation.RuleDetails
            };
        }
        catch
        {
            return new LicenseStatusInfo
            {
                Status = LicenseStatus.Expired,
                Message = "授权检查失败",
                CheckTime = DateTime.Now
            };
        }
    }

    ///// <summary>
    ///// 判断授权状态
    ///// </summary>
    //private static LicenseStatusInfo DetermineLicenseStatus(LicenseInfo licenseInfo, TimeValidationResult timeValidation)
    //{
    //    var now = timeValidation.CurrentTime;
    //    var expiryDate = licenseInfo.EndDate;

    //    // 🎯 新方案：基于授权生效日期实时计算使用天数
    //    var usedDays = SimpleTimeGuard.CalculateUsedDays(licenseInfo.StartDate, now);
    //    var remainingDays = licenseInfo.Days - usedDays;

    //    var statusInfo = new LicenseStatusInfo
    //    {
    //        ExpiryDate = expiryDate,
    //        CheckTime = now,
    //        RemainingDays = Math.Max(-1, remainingDays) // -1表示已过期
    //    };

    //    // 添加时间验证信息到消息中
    //    var timeInfo = timeValidation.IsFirstRun ? " (首次运行)" : "";

    //    // 情况1：未过期
    //    if (now <= expiryDate)
    //    {
    //        if (remainingDays <= 7 && remainingDays > 0)
    //        {
    //            statusInfo.Status = LicenseStatus.ExpiringSoon;
    //            statusInfo.Message = $"授权将在{remainingDays}天后到期{timeInfo}";
    //        }
    //        else
    //        {
    //            statusInfo.Status = LicenseStatus.Valid;
    //            statusInfo.Message = $"授权有效，剩余{remainingDays}天{timeInfo}";
    //        }

    //        return statusInfo;
    //    }

    //    // 情况2：已过期，检查宽限期
    //    if (LicenseGracePolicy.IsInGracePeriod(expiryDate, _applicationStartTime))
    //    {
    //        statusInfo.Status = LicenseStatus.ExpiredGracePeriod;

    //        var gracePeriod = new GracePeriodInfo
    //        {
    //            ExpiredDate = expiryDate,
    //            ApplicationStartDate = _applicationStartTime,
    //            GraceEndDate = expiryDate.AddDays(LicenseGracePolicy.GRACE_PERIOD_DAYS),
    //            HasGraceEligibility = LicenseGracePolicy.IsEligibleForGrace(expiryDate, _applicationStartTime),
    //            RemainingGraceTime = LicenseGracePolicy.GetRemainingGraceTime(expiryDate)
    //        };

    //        statusInfo.GracePeriod = gracePeriod;

    //        if (gracePeriod.IsExpiredToday)
    //        {
    //            statusInfo.Message = $"授权今日到期，明日将无法使用{timeInfo}";
    //        }
    //        else
    //        {
    //            var remainingHours = (int)gracePeriod.RemainingGraceTime.TotalHours;
    //            statusInfo.Message = $"授权已过期，宽限期剩余{remainingHours}小时{timeInfo}";
    //        }

    //        return statusInfo;
    //    }

    //    // 情况3：真正过期
    //    statusInfo.Status = LicenseStatus.Expired;
    //    statusInfo.Message = LicenseGracePolicy.IsEligibleForGrace(expiryDate, _applicationStartTime)
    //        ? $"宽限期已结束，授权已过期{timeInfo}"
    //        : $"启动时授权已过期{timeInfo}";

    //    return statusInfo;
    //}

    /// <summary>
    /// 验证授权码格式和签名
    /// </summary>
    /// <param name="licenseCode">授权码</param>
    /// <returns>授权信息，验证失败返回null</returns>
    public static LicenseInfo? ValidateLicenseCode(string licenseCode)
    {
        try
        {
            // 检查公钥文件是否存在
            if (!System.IO.File.Exists(PublicKeyFilePath))
                return null;

            var publicKeyXml = System.IO.File.ReadAllText(PublicKeyFilePath, Encoding.UTF8);

            // 解码Base64
            var jsonBytes = Convert.FromBase64String(licenseCode);
            var jsonData = Encoding.UTF8.GetString(jsonBytes);

            // 反序列化JSON
            var licenseData = JsonSerializer.Deserialize<LicenseData>(jsonData);
            if (licenseData == null || string.IsNullOrEmpty(licenseData.Signature))
                return null;

            // 提取签名
            var signature = Convert.FromBase64String(licenseData.Signature);

            // 创建用于验证的数据（不包含签名）
            var dataForVerification = new LicenseData
            {
                StartDate = licenseData.StartDate,
                Days = licenseData.Days,
                AgvCount = licenseData.AgvCount,
                MachineCode = licenseData.MachineCode
            };

            var verificationJson = JsonSerializer.Serialize(dataForVerification, new JsonSerializerOptions 
            { 
                WriteIndented = false 
            });

            // 使用公钥验证签名
            using var rsa = RSA.Create();
            rsa.FromXmlString(publicKeyXml);
            
            var dataBytes = Encoding.UTF8.GetBytes(verificationJson);
            var isSignatureValid = rsa.VerifyData(dataBytes, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);

            if (!isSignatureValid)
                return null;

            // 验证机器码（如果授权码包含机器码）
            if (!string.IsNullOrEmpty(licenseData.MachineCode))
            {
                if (!MachineCodeGenerator.ValidateMachineCode(licenseData.MachineCode, tolerance: 1))
                {
                    Console.WriteLine("[LicenseValidator] 机器码验证失败");
                    return null;
                }
                Console.WriteLine("[LicenseValidator] 机器码验证通过");
            }
            else
            {
                Console.WriteLine("[LicenseValidator] 跳过机器码验证");
            }

            // 解析日期
            if (!DateTime.TryParse(licenseData.StartDate, out var startDate))
                return null;

            // 返回授权信息
            return new LicenseInfo
            {
                StartDate = startDate,
                Days = licenseData.Days,
                AgvCount = licenseData.AgvCount,
                MachineCode = licenseData.MachineCode  // 添加机器码信息
            };
        }
        catch
        {
            return null;
        }
    }

    /// <summary>
    /// 检查注册风险和合法性
    /// </summary>
    /// <param name="newLicenseCode">新的授权码</param>
    /// <param name="allowDuplicateRegistration">是否允许重复注册相同授权码</param>
    /// <returns>注册检查结果</returns>
    private static DuplicateRegistrationResult CheckDuplicateRegistration(string newLicenseCode, bool allowDuplicateRegistration = false)
    {
        try
        {
            // 获取当前已注册的授权码
            var currentLicenseCode = UnifiedLicenseGuard.LoadLicense();

            // 情况1：首次注册
            if (string.IsNullOrEmpty(currentLicenseCode))
            {
                return new DuplicateRegistrationResult
                {
                    CanRegister = true,
                    RiskLevel = RegistrationRiskLevel.Safe,
                    Message = "首次注册，允许注册"
                };
            }

            // 检查当前授权状态
            var currentLicenseInfo = GetLicenseInfo();
            var isCurrentValid = false;
            int remainingDays = 0;

            if (currentLicenseInfo != null)
            {
                var validation = UnifiedLicenseGuard.ValidateLicense(currentLicenseInfo);
                isCurrentValid = validation.IsValid;
                remainingDays = validation.RemainingDays;
            }

            // 情况2：相同授权码
            if (currentLicenseCode == newLicenseCode)
            {
                if (isCurrentValid)
                {
                    if (allowDuplicateRegistration)
                    {
                        // 允许重复注册相同授权码，但需要确认
                        return new DuplicateRegistrationResult
                        {
                            CanRegister = true,
                            RiskLevel = RegistrationRiskLevel.SameLicense,
                            RequiresConfirmation = true,
                            Message = $"⚠️ 重复注册提醒：相同授权码已注册且有效（剩余{remainingDays}天）\n\n" +
                                     "重复注册将重置时间记录。请确认是否继续。"
                        };
                    }
                    else
                    {
                        // 不允许重复注册相同授权码
                        return new DuplicateRegistrationResult
                        {
                            CanRegister = false,
                            RiskLevel = RegistrationRiskLevel.SameLicense,
                            Message = $"相同授权码已注册且有效（剩余{remainingDays}天），不能重复注册"
                        };
                    }
                }
                else
                {
                    // 当前授权无效，允许重新注册
                    return new DuplicateRegistrationResult
                    {
                        CanRegister = true,
                        RiskLevel = RegistrationRiskLevel.Safe,
                        Message = "当前授权已失效，允许重新注册"
                    };
                }
            }

            // 情况3：不同授权码
            if (isCurrentValid)
            {
                // 当前授权有效，注册不同授权码需要确认风险
                return new DuplicateRegistrationResult
                {
                    CanRegister = true,
                    RiskLevel = RegistrationRiskLevel.DifferentLicense,
                    RequiresConfirmation = true,
                    Message = $"⚠️ 风险提醒：当前授权仍然有效（剩余{remainingDays}天）\n\n" +
                             "注册新授权码将替换当前授权。如果新授权码无效，将导致软件无法使用。\n\n" +
                             "请确认新授权码是从合法渠道获取的。"
                };
            }
            else
            {
                // 当前授权无效，允许注册新授权码
                return new DuplicateRegistrationResult
                {
                    CanRegister = true,
                    RiskLevel = RegistrationRiskLevel.Safe,
                    Message = "当前授权已失效，允许注册新授权码"
                };
            }
        }
        catch (Exception ex)
        {
            // 检查失败时，为了安全起见，允许注册但标记为需要确认
            return new DuplicateRegistrationResult
            {
                CanRegister = true,
                RiskLevel = RegistrationRiskLevel.DifferentLicense,
                RequiresConfirmation = true,
                Message = $"授权状态检查失败，建议谨慎操作: {ex.Message}"
            };
        }
    }

    /// <summary>
    /// 分析无授权的详细原因
    /// </summary>
    /// <returns>详细的错误信息</returns>
    private static string AnalyzeNoLicenseReason()
    {
        try
        {
            // 1. 检查是否有授权码文件
            var licenseCode = UnifiedLicenseGuard.LoadLicense();
            if (string.IsNullOrEmpty(licenseCode))
            {
                return "未找到授权码文件，请先注册授权码";
            }

            // 2. 检查授权码格式和签名
            var licenseInfo = ValidateLicenseCode(licenseCode);
            if (licenseInfo == null)
            {
                return "授权码格式错误或签名验证失败，请确认授权码和公钥是配套的";
            }

            // 3. 检查具体的验证失败原因
            var validation = UnifiedLicenseGuard.ValidateLicense(licenseInfo);
            if (!validation.IsValid)
            {
                return $"授权验证失败：{validation.Message}";
            }

            // 4. 如果都通过了，说明是其他未知原因
            return "授权验证过程中发生未知错误，请联系技术支持";
        }
        catch (Exception ex)
        {
            return $"授权检查异常：{ex.Message}";
        }
    }

    /// <summary>
    /// 获取注册风险信息（供UI层使用）
    /// </summary>
    /// <param name="licenseCode">要注册的授权码</param>
    /// <returns>注册风险检查结果</returns>
    public static DuplicateRegistrationResult GetRegistrationRisk(string licenseCode)
    {
        return CheckDuplicateRegistration(licenseCode);
    }

    /// <summary>
    /// 获取注册风险检查结果（支持重复注册控制）
    /// </summary>
    /// <param name="licenseCode">要注册的授权码</param>
    /// <param name="allowDuplicateRegistration">是否允许重复注册相同授权码</param>
    /// <returns>注册风险检查结果</returns>
    public static DuplicateRegistrationResult GetRegistrationRisk(string licenseCode, bool allowDuplicateRegistration)
    {
        return CheckDuplicateRegistration(licenseCode, allowDuplicateRegistration);
    }

    /// <summary>
    /// 清除授权信息
    /// </summary>
    /// <returns>是否清除成功</returns>
    public static bool ClearLicense()
    {
        try
        {
            // 🛠️ 修复：使用统一防护器清除所有记录（文件+注册表）
            UnifiedLicenseGuard.ClearAllRecords();

            // 清除缓存
            _cachedLicenseInfo = null;
            _lastCacheTime = DateTime.MinValue;

            return true;
        }
        catch
        {
            return false;
        }
    }
}

/// <summary>
/// 注册风险检查结果
/// </summary>
public class DuplicateRegistrationResult
{
    public bool CanRegister { get; set; }
    public string Message { get; set; } = "";
    public RegistrationRiskLevel RiskLevel { get; set; } = RegistrationRiskLevel.Safe;
    public bool RequiresConfirmation { get; set; } = false;
}

/// <summary>
/// 注册风险级别
/// </summary>
public enum RegistrationRiskLevel
{
    Safe,           // 安全：首次注册或过期后重新注册
    SameLicense,    // 相同授权码重复注册
    DifferentLicense // 不同授权码替换当前有效授权
}
